/*
 * ONE PLAYER AVOID (sucht den Node aus der am weitesten Weg ist vom Spieler und am nähsten an einem selbst dran ist)
 */

package de.hsb.ai.agent.misterx.targetmove;

import jade.core.AID;
import java.util.List;
import de.hsb.ai.agent.misterx.brain.Brain;
import de.hsb.ai.agent.misterx.brain.GraphAnalyser.DangerZone;


public class TargetMoveAvoid implements ITargetMove {

	int _currentInnerStrategy = 1;
	
	public TargetMoveAvoid() { }
	
	/**
	 * 
	 */
	@Override
	public int setup(int enemyCount) {
		if(enemyCount == 1) {
			this._currentInnerStrategy = 1;
		}
		if(enemyCount >= 2) {
			this._currentInnerStrategy = 2;
		}
		
		return DOES_ONE;
	}

	/**
	 * 
	 */
	@Override
	public int getNodeIndex() {
		if(this._currentInnerStrategy == 1) {
			return strategy_One();
		}
		if(this._currentInnerStrategy == 2) {
			return strategy_Multi();
		}
		
		return strategy_Multi();
	}
	
	
	/**
	 * nimmt den vom graph einem am nähstenliegenstern maxZone-Node des Gegners.
	 * 
	 * Filtert alle Nodes raus die am weitesten vom Gegner entfernt ist. (zb. Node 124, Node 23, Node 77 -> sind alle Radius 8 was der maximalen Distance in Wege des Gegner entspricht) 
	 * Danach wird die Menge geprüft ob einer der Nodes von mir selbst am nächsten ist (zb Node 124 = Radius 5, Node 23 = Radius 2, Node 77 = Radius 3) -> Auswahl Node 23 weil niedrigste Distanz.
	 * Zu diesem Node wird dann gegangen -> Node 23
	 * @return
	 */
	private int strategy_One() {
		int minRadius = Integer.MAX_VALUE;
		DangerZone minDangerZone = null;
		
		List<AID> enemy = Brain.getEnemyAIDs();
		for(int i = 0; i < enemy.size(); i++) {
			//Ermittle die maximal entferntesten Nodes eine Spielers.
			List<DangerZone> farDangerZones = Brain.GRAPHANALYSER.getMaxValueDangerZones(enemy.get(i));
			for(int j = 0; j < farDangerZones.size(); j++) {
				DangerZone farDangerZone = farDangerZones.get(j);
				
				//Ermittle alle Nodes bei MrX die auf die entferntesten Nodes des Spielers zutreffen.
				List<DangerZone> radiusDangerZones = Brain.GRAPHANALYSER.getDangerZonesByNodeIndex(farDangerZone._move.getNode());	
				for(int k = 0; k < radiusDangerZones.size(); k++) {
					DangerZone matchedDangerZone = radiusDangerZones.get(k);
					//nur MrX Nodes
					if(matchedDangerZone._aid.equals(Brain.getOwnAID())) {
						int currentRadius = matchedDangerZone._radius;
						if(currentRadius < minRadius) {
							minRadius = currentRadius;
							minDangerZone = matchedDangerZone;
						}
					}
				}
					
					
					
			}
		}
		return minDangerZone._move.getNode();
	}
	
	/**
	 * for each MaxZoneNode-allEnemies-
	 * MaxZoneNode=23_FromPlayer1"Radius=7" -> 	getNodeRadiusFromPlayer2(23) |	getNodeRadiusFromPlayer3(23) 
	 * 											zb.: Radius 2					zb.: Radius 3
	 * 
	 * 							Formel:			MaxRadiusP1 = 6					MaxRadiusP2 = 8
	 * 												-									-	
	 * 												Radius 2						Radius 3
	 * 												=									=
	 * 							value =				4					+				5			=  9    (0 = gutes MaxZoneNode  ,  > 0 = schlechtes MaxZoneNode)
	 * 
	 * bestRadiusSum = 9;
	 * bestNode = Node23;
	 * 
	 * if(value < bestRadiusSum) {
	 * 	bestRadiusSum = value;
	 * 	bestNode = MaxZoneNode;
	 * }
	 * 
	 * @return
	 */
	private int strategy_Multi() {
		List<AID> enemy = Brain.getEnemyAIDs();
		int value = -1;
		int nodeIndex = -1;
		
		for(int i = 0; i < enemy.size(); i++) {
			//Hole dir alle MaxValueDangerZones des Spielers
			List<DangerZone> farDangerZones = Brain.GRAPHANALYSER.getMaxValueDangerZones(enemy.get(i));
			
			//Gehe alle maximalen DangerZonen des Referenzspieler durch.
			for(DangerZone dangerZone : farDangerZones) {
				int currentValue = 0;
				
				//Kontrolliere alle Spieler ausser den Referenzspieler.
				for(int j = 0; j < enemy.size(); j++) {
					if(i != j) {
						AID currentEnemy = enemy.get(j);
						//Hole dir den Maximalen Radius des aktuellen Spielers
						int maxRadius = Brain.GRAPHANALYSER.getMaxZoneValue(currentEnemy);
					
						//Hole dir alle DangerNodes die auf den NodeIndex hören.
						List<DangerZone> sameIndexDangerZones = Brain.GRAPHANALYSER.getDangerZonesByNodeIndex(dangerZone._move.getNode());
						for(DangerZone sameIndexDangerZone : sameIndexDangerZones) {
							//hole dir davon aber nur den vom aktuell zu prüfenden Spieler.
							if(sameIndexDangerZone._aid.equals(currentEnemy)) {
								//Ziehe den maximalen Radius vom Radius des aktuellen Nodes ab.
								int radius = sameIndexDangerZone._radius;
								currentValue += maxRadius - radius;
							}
						}
					}
				}

				if(currentValue < value || value == -1) {
					value = currentValue;
					nodeIndex = dangerZone._move.getNode();
				}
			}
		}
		
		return nodeIndex;
	}
	
}
